package com.taobao.modules.monitor;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 
 * @author fangshi.lb
 * @date 2012/3/1
 */
public final class LinuxSystemMonitorTool {
	private static final Log log = LogFactory.getLog(LinuxSystemMonitorTool.class);

	/**
	 * 
	 * @return int[] result result.length==4; int[0]=MemTotal; int[1]=MemFree;
	 *         int[2]=SwapTotal; int[3]=SwapFree;
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public int[] getMemInfo() throws IOException, InterruptedException {
		log.debug("Get memory info");
		File file = new File("/proc/meminfo");
		BufferedReader br = new BufferedReader(new InputStreamReader(
				new FileInputStream(file)));
		int[] result = new int[4];
		String str = null;
		StringTokenizer token = null;
		while ((str = br.readLine()) != null) {
			token = new StringTokenizer(str);
			if (!token.hasMoreTokens())
				continue;

			str = token.nextToken();
			if (!token.hasMoreTokens())
				continue;

			if (str.equalsIgnoreCase("MemTotal:"))
				result[0] = Integer.parseInt(token.nextToken());
			else if (str.equalsIgnoreCase("MemFree:"))
				result[1] = Integer.parseInt(token.nextToken());
			else if (str.equalsIgnoreCase("SwapTotal:"))
				result[2] = Integer.parseInt(token.nextToken());
			else if (str.equalsIgnoreCase("SwapFree:"))
				result[3] = Integer.parseInt(token.nextToken());
		}
		return result;
	}

	/**
	 * 
	 * @return float efficiency
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public float getCpuInfo() throws IOException, InterruptedException {
		log.debug("Get cpu load info");
		File file = new File("/proc/stat");
		BufferedReader br = new BufferedReader(new InputStreamReader(
				new FileInputStream(file)));
		StringTokenizer token = new StringTokenizer(br.readLine());
		token.nextToken();
		int user1 = Integer.parseInt(token.nextToken());
		int nice1 = Integer.parseInt(token.nextToken());
		int sys1 = Integer.parseInt(token.nextToken());
		int idle1 = Integer.parseInt(token.nextToken());

		Thread.sleep(2000);

		br = new BufferedReader(
				new InputStreamReader(new FileInputStream(file)));
		token = new StringTokenizer(br.readLine());
		token.nextToken();
		int user2 = Integer.parseInt(token.nextToken());
		int nice2 = Integer.parseInt(token.nextToken());
		int sys2 = Integer.parseInt(token.nextToken());
		int idle2 = Integer.parseInt(token.nextToken());

		return (float) ((user2 + sys2 + nice2) - (user1 + sys1 + nice1))
				/ (float) ((user2 + nice2 + sys2 + idle2) - (user1 + nice1
						+ sys1 + idle1)) * 10;
	}

	/**
	 * 
	 * @throws IOException
	 */
	public static  String getCpuInfoPy() throws IOException { 
		log.debug("Get cpu info by scripts");
		Runtime rt = Runtime.getRuntime();
		Process p = rt.exec("python src/main/java/com/taobao/modules/scripts/cpu.py");
		BufferedReader in = null;
		String str = null;
		try {
			in = new BufferedReader(new InputStreamReader(p.getInputStream()));
			while ((str = in.readLine()) != null) {
				log.debug("cpu information str : " +str);
			}
		} catch (Exception e) {
			log.error("Failed to get cpu useage informations");
			e.printStackTrace();
		} finally {
			in.close();
		}
		return str;
	}

	/**
	 * get network information 
	 * @return
	 */
	public static String getNetworkInfo() {
		return "Not ok";
	}

	/**
	 * @return
	 * @throws Exception
	 */
	public static double getDiskInfo() throws Exception {
		double totalHD = 0;
		double usedHD = 0;
		Runtime rt = Runtime.getRuntime();
		Process p = rt.exec("df -hl");// df -hl
		BufferedReader in = null;
		try {
			in = new BufferedReader(new InputStreamReader(p.getInputStream()));
			String str = null;
			String[] strArray = null;
			int flag = 0;
			while ((str = in.readLine()) != null) {
				int m = 0;
				strArray = str.split(" ");
				for (String tmp : strArray) {
					if (tmp.trim().length() == 0)
						continue;
					++m;
					if (tmp.indexOf("G") != -1) {
						if (m == 2) {
							// System.out.println("---G----" + tmp);
							if (!tmp.equals("") && !tmp.equals("0"))
								totalHD += Double.parseDouble(tmp.substring(0,
										tmp.length() - 1)) * 1024;
						}
						if (m == 3) {
							// System.out.println("---G----" + tmp);
							if (!tmp.equals("none") && !tmp.equals("0"))
								usedHD += Double.parseDouble(tmp.substring(0,
										tmp.length() - 1)) * 1024;
						}
					}
					if (tmp.indexOf("M") != -1) {
						if (m == 2) {
							// System.out.println("---M---" + tmp);
							if (!tmp.equals("") && !tmp.equals("0"))
								totalHD += Double.parseDouble(tmp.substring(0,
										tmp.length() - 1));
						}
						if (m == 3) {
							// System.out.println("---M---" + tmp);
							if (!tmp.equals("none") && !tmp.equals("0"))
								usedHD += Double.parseDouble(tmp.substring(0,
										tmp.length() - 1));
							// System.out.println("----3----" + usedHD);
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			in.close();
		}
		return (usedHD / totalHD) * 100;
	}

	public static void print(String str) {
		System.out.println(str);
	}

	public void getSystemInfo() {
		String cpu_cmd = "grep 'processor' /proc/cpuinfo | wc -l";

		String username = System.getProperty("user.name");
		System.out.println("username         : " + username);

		String osname = System.getProperty("os.name");
		System.out.println("osname           : " + osname);

		String os_version = System.getProperty("os.version");
		System.out.println("os_version       : " + os_version);

		String os_arch = System.getProperty("os.arch");
		System.out.println("os_arch          : " + os_arch);

		String usr_dir = System.getProperty("user.dir");
		System.out.println("usr_dir          : " + usr_dir);
	}

	public static void getJAVAInfo() {
		String java_version = System.getProperty("java.version");
		System.out.println("java_version     : " + java_version);

		String java_home = System.getProperty("java.home");
		System.out.println("java_home        : " + java_home);

		String java_vm_version = System.getProperty("java.vm.version");
		System.out.println("java_vm_version  : " + java_vm_version);

		String java_class_path = System.getProperty("java.class.path");
		System.out.println("java_class_path  : " + java_class_path);

		String java_library_path = System.getProperty("java.library.path");
		System.out.println("java_library_path: " + java_library_path);

		//
		Runtime runtime = Runtime.getRuntime();
		Long java_freememory = runtime.freeMemory();
		System.out.println("java freemory    : " + java_freememory);

		System.out.println("Avaible Process  : "
				+ runtime.availableProcessors());

	}

	public static void main(String[] args) throws Exception {
		LinuxSystemMonitorTool tools = new LinuxSystemMonitorTool();

		System.out.println("---------------------------JAVA INFO-------------------------------------------");
		LinuxSystemMonitorTool.getJAVAInfo();

		if (System.getProperty("os.name").equals("linux")) {
			System.out.println("---------------------------OS INFO---------------------------------------------");
			tools.getSystemInfo();

			System.out.println("---------------------------JAVA INFO-------------------------------------------");
			LinuxSystemMonitorTool.getJAVAInfo();

			System.out.println("---------------------------MEM INFO-------------------------------");
			int[] memInfo = tools.getMemInfo();
			System.out.println("MemTotal         : " + memInfo[0]);
			System.out.println("MemFree          : " + memInfo[1]);
			System.out.println("SwapTotal        : " + memInfo[2]);
			System.out.println("SwapFree         : " + memInfo[3]);

			System.out.println("---------------------------CPU INFO-------------------------------");
			System.out.println("CPU              : " + tools.getCpuInfo());

			System.out.println("---------------------------DISK INFO------------------------------");
			System.out.println(LinuxSystemMonitorTool.getDiskInfo());

			System.out.println("---------------------------NETWORK INFO---------------------------");
			System.out.println(LinuxSystemMonitorTool.getNetworkInfo());
		}
		;

		LinuxSystemMonitorTool.getCpuInfoPy();
	}
}
